From fa961865760b70859952aa66e30b2d6dd794d3a1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 14 Nov 2005 19:55:40 +0100 Subject: [PATCH] get_page_type() must clean up writable pagetable state before failing, otherwise functions like set_gdt() can spuriously fail because a page appears to be writable despite there being pending changes to mapping of that page in ptwr state. This should fix the reported cases of crashes in vcpu_prepare in xenlinux. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 47b0f97d9d..6c9dfbd6cc 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1461,6 +1461,22 @@ int get_page_type(struct pfn_info *page, unsigned long type) { if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) ) { + if ( current->domain == page_get_owner(page) ) + { + /* + * This ensures functions like set_gdt() see up-to-date + * type info without needing to clean up writable p.t. + * state on the fast path. + */ + LOCK_BIGLOCK(current->domain); + cleanup_writable_pagetable(current->domain); + y = page->u.inuse.type_info; + UNLOCK_BIGLOCK(current->domain); + /* Can we make progress now? */ + if ( ((y & PGT_type_mask) == (type & PGT_type_mask)) || + ((y & PGT_count_mask) == 0) ) + goto again; + } if ( ((x & PGT_type_mask) != PGT_l2_page_table) || ((type & PGT_type_mask) != PGT_l1_page_table) ) MEM_LOG("Bad type (saw %" PRtype_info -- 2.30.2